package com.kpi.processflow.runner;

import com.google.common.collect.Lists;
import com.kpi.processflow.node.Node;
import com.kpi.processflow.node.NodeRegistry;
import com.kpi.processflow.process.Process;
import com.kpi.processflow.process.reader.ProcessDefinitionReader;
import com.kpi.processflow.process.registry.ProcessDefinitionRegistry;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.Collection;
import java.util.List;

/**
 * @author Kevin Liu
 * @date 2020/5/3 9:50 下午
 */
@Slf4j
public class ProcessNodeAssembler implements CommandLineRunner {

    private NodeRegistry nodeRegistry;

    private ProcessDefinitionRegistry registry;

    private ProcessDefinitionReader reader;

    public ProcessNodeAssembler(NodeRegistry nodeRegistry, ProcessDefinitionRegistry registry, ProcessDefinitionReader reader) {
        this.nodeRegistry = nodeRegistry;
        this.registry = registry;
        this.reader = reader;
    }

    @Override
    public void run(String... args) throws Exception {
        Collection<Process> processes = reader.loadProcessDefinition();
        if(CollectionUtils.isEmpty(processes)) {
            return;
        }
        List<Node> processNodes;
        for (Process process : processes) {
            List<String> nodeNames = process.getNodeList();
            if (CollectionUtils.isEmpty(nodeNames)) {
                continue;
            }
            processNodes = Lists.newArrayList();
            for (String nodeName : nodeNames) {
                Node node = nodeRegistry.getNode(nodeName);
                if (node == null) {
                    log.error("don't find candidate node bean when build process, node name : {}", nodeName);
                    throw new RuntimeException("don't find candidate node bean when build process");
                }
                processNodes.add(node);
            }
            registry.registryProcess(process, processNodes);
        }
    }
}
